import { proxy } from 'valtio'
import { derive } from 'derive-valtio'
import { storage } from '@/utils/storage'

const cache = new Map<string, any>()

export type UserState = {
  geo: Data | null
  openid: string
  userInfo: Data | null
}

const setValue = <V>(key: string, value: V | null) => {
  if (value === null) {
    cache.delete(key)
    storage.removeItem(key)
  } else {
    cache.set(key, value)
    storage.setItem(key, value)
  }
}

export const userState = proxy<UserState>({
  get geo(): Data | null {
    return cache.get('geo') ?? null
  },
  set geo(value: Data | null) {
    setValue('geo', value)
  },
  get openid(): string {
    return cache.get('openid') ?? ''
  },
  set openid(value: string) {
    setValue('openid', value)
  },
  get userInfo(): Data | null {
    return cache.get('userInfo') ?? null
  },
  set userInfo(value: Data | null) {
    setValue('userInfo', value)
  },
})

export const derivedState = derive({
  city: (get) => get(userState).geo?.city ?? '',
  province: (get) => get(userState).geo?.province ?? '',
  balance: (get) => get(userState).userInfo?.balance ?? 0,
  isAuthed: (get) => Boolean(get(userState).userInfo?.mobile),
})

export default derivedState

function initialize() {
  const geo = storage.getItem('geo')
  const openid = storage.getItem('openid')
  const userInfo = storage.getItem('userInfo')

  geo && cache.set('geo', geo)
  openid && cache.set('openid', openid)
  userInfo && cache.set('userInfo', userInfo)
}

initialize()
